package cn.genmer.test.security.io.compression;

import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.FileHeader;

import java.io.*;
import java.util.List;



public class readZipWithPassword {
    public static void main(String[] args) {

        try {
            String s = readFromZipWithPassword("D:\\program\\work\\hbdata\\565295d5-6fa8-4bb0-8fd1-c1630e7b2814.zip", "1");
            System.out.println(s);
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 读取一个带密码的压缩文件的文件内容
     * @param zipFile 压缩文件
     * @param password 密码
     * @throws ZipException
     * @return
     */
    public static String readFromZipWithPassword(String zipFile, String password) throws IOException, ZipException {
        long startTime = System.currentTimeMillis();
        ZipFile zipFile2 = new ZipFile(zipFile);
        //设置编码格式
        zipFile2.setFileNameCharset("GBK");
        if (!zipFile2.isValidZipFile()) {
            throw new ZipException("文件不合法或不存在");
        }
        //检查是否需要密码
        if (zipFile2.isEncrypted()) {
            zipFile2.setPassword(password.toCharArray());
        }
        StringBuilder builder = new StringBuilder();
        List<FileHeader> fileHeaderList = zipFile2.getFileHeaders();
        for (int i = 0; i < fileHeaderList.size(); i++) {
            FileHeader fileHeader = fileHeaderList.get(i);
            BufferedReader reader = new BufferedReader(new InputStreamReader(zipFile2.getInputStream(fileHeader), "GBK"));
            String line;

            try {
                while ( ( line = reader.readLine() ) != null) {
                    builder.append( new String(line.getBytes("UTF-16LE"), "UTF-8"));
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        System.out.println("解压成功！");
        long endTime = System.currentTimeMillis();
        System.out.println("耗时：" + (endTime - startTime) + "ms");
        return builder.toString();
    }


    public static String getFileEncode(String path) {
        String charset ="asci";
        byte[] first3Bytes = new byte[3];
        BufferedInputStream bis = null;
        try {
            boolean checked = false;
            bis = new BufferedInputStream(new FileInputStream(path));
            bis.mark(0);
            int read = bis.read(first3Bytes, 0, 3);
            if (read == -1)
                return charset;
            if (first3Bytes[0] == (byte) 0xFF && first3Bytes[1] == (byte) 0xFE) {
                charset = "Unicode";//UTF-16LE
                checked = true;
            } else if (first3Bytes[0] == (byte) 0xFE && first3Bytes[1] == (byte) 0xFF) {
                charset = "Unicode";//UTF-16BE
                checked = true;
            } else if (first3Bytes[0] == (byte) 0xEF && first3Bytes[1] == (byte) 0xBB && first3Bytes[2] == (byte) 0xBF) {
                charset = "UTF8";
                checked = true;
            }
            bis.reset();
            if (!checked) {
                int len = 0;
                int loc = 0;
                while ((read = bis.read()) != -1) {
                    loc++;
                    if (read >= 0xF0)
                        break;
                    if (0x80 <= read && read <= 0xBF) //单独出现BF以下的，也算是GBK
                        break;
                    if (0xC0 <= read && read <= 0xDF) {
                        read = bis.read();
                        if (0x80 <= read && read <= 0xBF)
                            //双字节 (0xC0 - 0xDF) (0x80 - 0xBF),也可能在GB编码内
                            continue;
                        else
                            break;
                    } else if (0xE0 <= read && read <= 0xEF) { //也有可能出错，但是几率较小
                        read = bis.read();
                        if (0x80 <= read && read <= 0xBF) {
                            read = bis.read();
                            if (0x80 <= read && read <= 0xBF) {
                                charset = "UTF-8";
                                break;
                            } else
                                break;
                        } else
                            break;
                    }
                }
                //TextLogger.getLogger().info(loc + " " + Integer.toHexString(read));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException ex) {
                }
            }
        }
        return charset;
    }

//    public static test() throws IOException {
//        InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(
//                new File(new File("").getCanonicalPath() + "\\bin\\wz.txt")), "UTF-16LE");//UTF-16LE就是UCS-2
//
//    }

}
